package m.system.listener;

import api.util.ApiConvertDataSupport;
import m.appserver.AppServerUtil;
import m.common.netty.HostNettyUtil;
import m.common.service.HostInfoService;
import m.system.RuntimeData;
import m.system.SystemInit;
import m.system.cache.SynchServer;
import m.system.cache.redis.RedisConfig;
import m.system.db.DBConfig;
import m.system.db.TransactionManager;
import m.system.exception.MException;
import m.system.handler.InitHandler;
import m.system.task.TaskUtil;
import m.system.url.UrlMarker;
import m.system.util.StringUtil;
import m.system.util.SystemUtil;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Properties;

public class InitListener {

	public static void destroyed() {
		ApiConvertDataSupport.close();//关闭数据转换支撑
		SynchServer.close();
		try {//关闭初始化任务
			SystemInit.initClassClose(RuntimeData.getInitClass());
		} catch (Exception ignored) {}
		TransactionManager.closeConnection();
		TransactionManager.closeAllConection();
		HostNettyUtil.closeAll();
		TaskUtil.closeTask();
	}
	
	private static void loadConfig(String path) throws IOException {
		InputStream inputStream = AppServerUtil.loadConfig(path,"config/mconfig.properties");
		if(null!=inputStream) {
			Properties p = new Properties();
			p.load(inputStream);
			if(!StringUtil.isSpace(p.getProperty("file_path"))) RuntimeData.setFilePath(p.getProperty("file_path"));
			if(!StringUtil.isSpace(p.getProperty("secret_field"))) RuntimeData.setSecretField(p.getProperty("secret_field"));
			if(!StringUtil.isSpace(p.getProperty("static_field"))) RuntimeData.setStaticField(p.getProperty("static_field"));
			if(!StringUtil.isSpace(p.getProperty("model_pack"))) RuntimeData.setModelPack(p.getProperty("model_pack"));
			if(!StringUtil.isSpace(p.getProperty("action_pack"))) RuntimeData.setActionPack(p.getProperty("action_pack"));
			if(!StringUtil.isSpace(p.getProperty("handler_pack"))) RuntimeData.setHandlerPack(p.getProperty("handler_pack"));
			if(!StringUtil.isSpace(p.getProperty("domain_class"))) RuntimeData.setDomainClass(p.getProperty("domain_class"));
			if(!StringUtil.isSpace(p.getProperty("task_class"))) RuntimeData.setTaskClass(p.getProperty("task_class"));
			if(!StringUtil.isSpace(p.getProperty("init_class"))) RuntimeData.setInitClass(p.getProperty("init_class"));
			if(!StringUtil.isSpace(p.getProperty("filter_class"))) RuntimeData.setFilterClass(p.getProperty("filter_class"));
		}
		InputStream dbStream = AppServerUtil.loadConfig(path,"dbconfig.properties");
		if(null!=dbStream) {
			Properties dbp = new Properties();
			dbp.load(dbStream);
			//数据库配置
			if(!StringUtil.isSpace(dbp.getProperty("db_driver"))) DBConfig.setDriver(dbp.getProperty("db_driver"));
			if(!StringUtil.isSpace(dbp.getProperty("db_url"))) DBConfig.setUrl(dbp.getProperty("db_url"));
			if(!StringUtil.isSpace(dbp.getProperty("db_username"))) DBConfig.setUsername(dbp.getProperty("db_username"));
			if(!StringUtil.isSpace(dbp.getProperty("db_password"))) DBConfig.setPassword(dbp.getProperty("db_password"));
			if(!StringUtil.isSpace(dbp.getProperty("db_init_connect"))) DBConfig.setInitConnect(dbp.getProperty("db_init_connect"));
			if(!StringUtil.isSpace(dbp.getProperty("db_max_connect"))) DBConfig.setMaxConnect(Integer.parseInt(dbp.getProperty("db_max_connect","20")));
			if(!StringUtil.isSpace(dbp.getProperty("db_query_timeout"))) DBConfig.setQueryTimeout(Integer.parseInt(dbp.getProperty("db_query_timeout", "600")));

			if(!StringUtil.isSpace(dbp.getProperty("table_schema"))) RuntimeData.setTableSchema(dbp.getProperty("table_schema"));
			//redis配置
			if(!StringUtil.isSpace(dbp.getProperty("redis_ip"))) RedisConfig.setIp(dbp.getProperty("redis_ip"));
			if(!StringUtil.isSpace(dbp.getProperty("redis_port"))) RedisConfig.setPort(Integer.parseInt(dbp.getProperty("redis_port", "6379")));
			if(!StringUtil.isSpace(dbp.getProperty("redis_auth"))) RedisConfig.setAuth(dbp.getProperty("redis_auth"));
			//服务配置
			if(!StringUtil.isSpace(dbp.getProperty("server_ip"))) RuntimeData.setServerIp(dbp.getProperty("server_ip"));
			if(!StringUtil.isSpace(dbp.getProperty("server_port"))) RuntimeData.setServerPort(Integer.parseInt(dbp.getProperty("server_port","8128").trim()));
			if(!StringUtil.isSpace(dbp.getProperty("server_auth"))) RuntimeData.setServerAuth(dbp.getProperty("server_auth"));
			if(!StringUtil.isSpace(dbp.getProperty("server_name"))) RuntimeData.setServerName(dbp.getProperty("server_name"));

			if(!StringUtil.isSpace(dbp.getProperty("debug"))) RuntimeData.setDebug(dbp.getProperty("debug").equals("true"));
			if(!StringUtil.isSpace(dbp.getProperty("out_log"))) RuntimeData.setOutLog(dbp.getProperty("out_log").equals("true"));
		}
	}
	private static boolean isInit=false;
	/**
	 * 初始化DB  此方法用于main方法开始
	 *  path
	 */
	public static void initDB(String path) throws IOException, MException, ClassNotFoundException {
		if(isInit) return;//初始化只调用一次
		isInit=true;
		//必要参数
		if(null!=path) {
			RuntimeData.setClassPath(path);
			RuntimeData.setPublicPath(path.substring(0,path.substring(0,path.length()-1).lastIndexOf("//")+1));
		}
		//加载配置信息
		loadConfig(null);//默认配置信息
		if(null!=path) {
			loadConfig(path);//路径下的配置信息  存在则覆盖默认配置
		}
		RuntimeData.addActionPack("manage.action");
		RuntimeData.addActionPack("flow.action");//流程相关
		RuntimeData.addActionPack("api.action");//api相关
		RuntimeData.addModelPack("manage.model");
		RuntimeData.addModelPack("flow.model");//流程相关
		RuntimeData.addModelPack("api.model");//api相关
		RuntimeData.addHandlerPack("m.system.handler");
		RuntimeData.addStaticField("ImageInfo.imgPath","ImageInfo.thumPath","IconInfo.path");
		RuntimeData.addSecretField("AdminLogin.password","AdminLogin.token");
		SynchServer.init();//初始化同步服务
		ApiConvertDataSupport.init();//初始化数据转换支撑
		//初始化表信息
		SystemInit.initModel(RuntimeData.getModelPack());
	}

	/**
	 * 系统初始化方法
	 *  path  需要/结尾
	 *  jar
	 *  serverPort
	 */
	public static boolean init(String path,String jar,int serverPort){
		if(isInit) return false;//初始化只调用一次
		isInit=true;
		try {
			long t=new Date().getTime();
			//必要参数
			RuntimeData.setClassPath(path);
			RuntimeData.setPublicPath(path.substring(0,path.substring(0,path.length()-1).lastIndexOf("/")+1));
			//删除临时目录
			RuntimeData.clearTmpFile();
			
			//加载配置信息
			loadConfig(null);//默认配置信息
			loadConfig(path);//路径下的配置信息  存在则覆盖默认配置
			RuntimeData.addInitClass("manage.run.ModuleInitRun");
			SynchServer.init();//初始化同步服务
			ApiConvertDataSupport.init();//初始化数据转换支撑
			//执行初始化类的init方法
			SystemInit.initClassInit(RuntimeData.getInitClass());
			if(!StringUtil.isSpace(RuntimeData.getTableSchema())){
				//配置数据库名,配置则自动检测生成表结构
				SystemInit.setTableSchema(RuntimeData.getTableSchema());
			}
			//初始化表信息
			SystemInit.initModel(RuntimeData.getModelPack());
			//初始化服务信息
			SystemInit.initServerGroup(RuntimeData.getServerIp(), RuntimeData.getServerPort());
			HostInfoService.getCurrentHost().setServerPort(serverPort);//设置服务端口
			HostInfoService.getCurrentHost().setJarName(jar);//设置执行的jar名称
			//自动检测生成表结构
			SystemInit.initModelTable();
			//初始化执行定时任务
			SystemInit.taskClassRun(RuntimeData.getTaskClass());
			//执行初始化execute => 实现类的run方法
			SystemInit.initClassRun(RuntimeData.getInitClass());
			//初始化Action
			SystemInit.initAction(RuntimeData.getActionPack());
			//初始化Handler
			InitHandler.init(RuntimeData.getHandlerPack());
			//初始化url配置
			UrlMarker.initXML();
			SystemUtil.printlnIf(true,"--- 系统初始化完成，",new Date().getTime()-t,"ms ---");
			return true;
		} catch (Exception e1) {
			SystemUtil.printlnIf(true,"系统初始化失败!",e1.getMessage());
			e1.printStackTrace();
			return false;
		}
	}
}
